package cn.com.libertymutual.core.database.druid.config;


import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

import cn.com.libertymutual.core.common.util.ApplicationContextUtil;
import cn.com.libertymutual.core.database.druid.DataSourceType;

@Configuration
@EnableJpaRepositories(value = "cn.com.libertymutual.*.dao",
entityManagerFactoryRef = "salePlatEntityManagerFactory", 
transactionManagerRef = "salePlatTransactionManager")
public class SalePlatDataSourceManager {
	private Logger log = LoggerFactory.getLogger(getClass());
	
	@Value("${spring.datasource.readSize}")
	private String dataSourceSize;
	
	@Autowired
	JpaProperties jpaProperties;
	
	@Autowired
	@Qualifier("writeDataSource")
	private DruidDataSource writeDataSource;

	/**
	 * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory
	 * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session,
	 * mybatis的sqlSession.
	 * 
	 * @return
	 */
	@Bean(name = "salePlatEntityManagerFactory")
	@Primary
	public EntityManagerFactory salePlatEntityManagerFactory() {
		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
		factory.setJpaVendorAdapter(vendorAdapter);
		factory.setPackagesToScan("cn.com.libertymutual.*.bean");
		factory.setDataSource(roundRobinDataSouceProxy());// 数据源
		factory.setJpaPropertyMap(jpaProperties.getProperties());
		factory.afterPropertiesSet();// 在完成了其它所有相关的配置加载以及属性设置后,才初始化
		return factory.getObject();
	}
	@Bean(name = "roundRobinDataSouceProxy")
	public AbstractRoutingDataSource roundRobinDataSouceProxy() {
		int size = Integer.parseInt(dataSourceSize);
		SalePlatAbstractRoutingDataSource proxy = new SalePlatAbstractRoutingDataSource(
				size);
		Map<Object, Object> targetDataSources = new HashMap<Object, Object>();

		DruidDataSource writeDataSource = ApplicationContextUtil.getBean(
				"writeDataSource", DruidDataSource.class);
		// 写
		targetDataSources.put(DataSourceType.write.getType(), writeDataSource);
		DataSource readDataSource = null;
		for (int i = 0; i < size; i++) {
			readDataSource = ApplicationContextUtil.getBean("readDataSource"
					+ (i + 1), DruidDataSource.class);
			targetDataSources.put(i, readDataSource);
		}
		proxy.setDefaultTargetDataSource(writeDataSource);
		proxy.setTargetDataSources(targetDataSources);
		return proxy;
	}

	/**
	 * 配置事物管理器
	 * 
	 * @return
	 */
	@Bean(name = "salePlatTransactionManager")
	@Primary
	public PlatformTransactionManager writeTransactionManager() {
		JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
		jpaTransactionManager.setEntityManagerFactory(this
				.salePlatEntityManagerFactory());
		return jpaTransactionManager;
	}
}
